package at.ac.univie.zsu.aguataplan.ui.template;

import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.DefaultListModel;
import javax.swing.JComboBox;
import javax.swing.JDialog;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;

import org.jdesktop.swingx.JXList;

import at.ac.univie.zsu.aguataplan.domain.DetectedEvent;
import at.ac.univie.zsu.aguataplan.property.GeneralProperties;
import at.ac.univie.zsu.aguataplan.property.I18nProperties;
import at.ac.univie.zsu.aguataplan.ui.UIConstants;

/**
 * TODO: there is a refresh of all components no matter if operation works -
 * maybe not necessary
 * 
 * @author gerry
 * 
 */
public class ListPanel extends JPanel implements UIConstants {

	private static final long serialVersionUID = 1L;

	// general members
	private JDialog dialogParent;
	private GeneralProperties generalProperties;
	private I18nProperties i18nProp;
	private IDialogList iDialogList;

	// list
	private JScrollPane listScroll;
	private JXList list;
	private DefaultListModel listModel;
	private JComboBox comboBox;

	private List<ListPanel> parents;
	private List<ListPanel> children;

	// ----------------------------------------------------
	// CONSTRUCTOR
	// ----------------------------------------------------

	public ListPanel(JDialog dialogParent, GeneralProperties generalProperties, IDialogList iDialog) {

		this.dialogParent = dialogParent;
		this.generalProperties = generalProperties;
		this.i18nProp = generalProperties.getI18nProperties();
		this.iDialogList = iDialog;

		parents = new ArrayList<ListPanel>();
		children = new ArrayList<ListPanel>();

		this.setLayout(null);

	}

	// ----------------------------------------------------
	// METHODS
	// ----------------------------------------------------

	public void addChild(ListPanel entryPanel) {
		children.add(entryPanel);
	}

	public void addParent(ListPanel entryPanel) {
		parents.add(entryPanel);
	}

	public void init(String borderName, int sizeX, int sizeY, boolean combo) {

		this.setBorder(javax.swing.BorderFactory.createTitledBorder(borderName));

		listScroll = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
				JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
		list = new JXList();
		list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		list.setModel(getListModel());

		if (combo) {
			listScroll.setSize(sizeX - SPACING_BIG, sizeY - 30 - SPACING_BIG - SPACING);
		} else {
			listScroll.setSize(sizeX - SPACING_BIG, sizeY - 30);
		}
		listScroll.setLocation(LIST_LOCATION_X, LIST_LOCATION_Y);

		listScroll.getViewport().add(list);
		this.add(listScroll);

		initListModel();

		if (combo) {
			initComboBox(sizeX, sizeY);
		}

		// Listener
		// -------------------------------
		// click on free area
		addMouseListener(new java.awt.event.MouseAdapter() {
			public void mouseClicked(java.awt.event.MouseEvent evt) {

				cleanText();

				// disable children
				disableChildren();

			}
		});

		// click on list to select entry
		list.addMouseListener(new java.awt.event.MouseAdapter() {
			public void mouseClicked(java.awt.event.MouseEvent evt) {
				if (evt.getClickCount() == 1) {
					Object obj = list.getSelectedValue();
					if (obj == null) {
						return;
					}

				} else if (evt.getClickCount() == 2) {
					Object obj = list.getSelectedValue();
					if (obj == null) {
						return;
					}
					iDialogList.registerDoubleClick(obj);
				}

				// init children
				for (ListPanel c : children) {
					c.initListModel();
				}

			}
		});

		this.setSize(sizeX, sizeY);
		setVisible(true);
	}

	public void finishInit() {
		disableChildren();
	}

	public void reInit(String borderName) {
		this.setBorder(javax.swing.BorderFactory.createTitledBorder(borderName));
		initListModel();
	}

	// ----------------------------------------------------
	// METHODS PRIVATE
	// ----------------------------------------------------

	private ListModel getListModel() {

		if (listModel == null) {
			listModel = new DefaultListModel();

		}
		return listModel;
	}

	private void initListModel() {
		disableButton();
		List<?> list;
		if ((list = iDialogList.initText()) != null) {
			listModel.clear();
			for (Object o : list) {
				listModel.addElement(o);
			}
		}

		enableButton();
	}

	private void initComboBox(int sizeX, int sizeY) {
		comboBox = new JComboBox();

		comboBox.setSize(sizeX - SPACING_BIG, COMBO_SIZE_Y);
		comboBox.setLocation(0 + SPACING + SPACING, sizeY - SPACING_BIG - SPACING - SPACING);

		comboBox.addItemListener(new ItemListener() {

			@Override
			public void itemStateChanged(ItemEvent e) {
				Object obj = comboBox.getSelectedItem();

				// TODO: obj == null used for select everything - maybe change
				// that
				// if (obj == null) {
				// return;
				// }

				List<DetectedEvent> list = iDialogList.selectDestectedEvent(obj);

				listModel.clear();
				for (DetectedEvent de : list) {
					listModel.addElement(de);
				}

			}
		});

		List<?> list;
		if ((list = iDialogList.initCombo()) != null) {
			for (Object o : list) {
				comboBox.addItem(o);
			}
		}

		this.add(comboBox);

	}

	private void disableChildren() {
		for (ListPanel c : children) {
			c.disableButton();
		}
	}

	private void cleanText() {

		// clean list selection
		list.clearSelection();
	}

	private void disableButton() {

		// disable list
		listModel.clear();
		list.setEnabled(false);

	}

	private void enableButton() {
		// enable list
		list.setEnabled(true);

	}

	public Object getSelectedValueEntry() {
		return list.getSelectedValue();
	}

}
